domid_t domid;
unsigned int handle;
+ u8 fe_dev_addr[6];
+
/* Physical parameters of the comms window. */
unsigned long tx_shmem_frame;
unsigned long rx_shmem_frame;
/* Disable queuing. */
dev->tx_queue_len = 0;
- /*
- * Initialise a dummy MAC address. We choose the numerically largest
- * non-broadcast address to prevent the address getting stolen by an
- * Ethernet bridge for STP purposes. (FE:FF:FF:FF:FF:FF)
- */
- memset(dev->dev_addr, 0xFF, ETH_ALEN);
- dev->dev_addr[0] &= ~0x01;
+ if ( (create->be_mac[0] == 0) && (create->be_mac[1] == 0) &&
+ (create->be_mac[2] == 0) && (create->be_mac[3] == 0) &&
+ (create->be_mac[4] == 0) && (create->be_mac[5] == 0) )
+ {
+ /*
+ * Initialise a dummy MAC address. We choose the numerically largest
+ * non-broadcast address to prevent the address getting stolen by an
+ * Ethernet bridge for STP purposes. (FE:FF:FF:FF:FF:FF)
+ */
+ memset(dev->dev_addr, 0xFF, ETH_ALEN);
+ dev->dev_addr[0] &= ~0x01;
+ }
+ else
+ {
+ memcpy(dev->dev_addr, create->be_mac, ETH_ALEN);
+ }
+
+ memcpy(netif->fe_dev_addr, create->mac, ETH_ALEN);
rtnl_lock();
err = register_netdevice(dev);
P2C(netif_be_create_t, mac[3], u8);
P2C(netif_be_create_t, mac[4], u8);
P2C(netif_be_create_t, mac[5], u8);
+ P2C(netif_be_create_t, be_mac[0], u8);
+ P2C(netif_be_create_t, be_mac[1], u8);
+ P2C(netif_be_create_t, be_mac[2], u8);
+ P2C(netif_be_create_t, be_mac[3], u8);
+ P2C(netif_be_create_t, be_mac[4], u8);
+ P2C(netif_be_create_t, be_mac[5], u8);
break;
case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DESTROY):
P2C(netif_be_destroy_t, domid, u32);
(major, minor) = msg_formats[ty]
args = {}
for (k, v) in params.items():
- if k == 'mac':
+ if k in ['mac', 'be_mac']:
for i in range(0, 6):
- args['mac[%d]' % i] = v[i]
+ args['%s[%d]' % (k, i)] = v[i]
else:
args[k] = v
msg = xu.message(major, minor, msgid, args)
vmac = sxp.child_value(config, 'mac')
if not vmac: return None
mac = [ int(x, 16) for x in vmac.split(':') ]
- if len(mac) != 6: raise XendError("invalid mac")
+ if len(mac) != 6: raise XendError("invalid mac: %s" % vmac)
+ return mac
+
+ def _get_config_be_mac(self, config):
+ vmac = sxp.child_value(config, 'be_mac')
+ if not vmac: return None
+ mac = [ int(x, 16) for x in vmac.split(':') ]
+ if len(mac) != 6: raise XendError("invalid backend mac: %s" % vmac)
return mac
def _get_config_ipaddr(self, config):
return self.reconfigure(config)
self.config = config
self.mac = None
+ self.be_mac = None
self.bridge = None
self.script = None
self.ipaddr = []
if mac is None:
raise XendError("invalid mac")
self.mac = mac
+ self.be_mac = self._get_config_be_mac(config)
self.bridge = sxp.child_value(config, 'bridge')
self.script = sxp.child_value(config, 'script')
self.ipaddr = self._get_config_ipaddr(config) or []
"""
changes = {}
mac = self._get_config_mac(config)
+ be_mac = self._get_config_be_mac(config)
bridge = sxp.child_value(config, 'bridge')
script = sxp.child_value(config, 'script')
ipaddr = self._get_config_ipaddr(config)
backendDomain = str(xd.domain_lookup(sxp.child_value(config, 'backend', '0')).id)
if (mac is not None) and (mac != self.mac):
raise XendError("cannot change mac")
+ if (be_mac is not None) and (be_mac != self.be_mac):
+ raise XendError("cannot change backend mac")
if (backendDomain is not None) and (backendDomain != str(self.backendDomain)):
raise XendError("cannot change backend")
if (bridge is not None) and (bridge != self.bridge):
['idx', self.idx],
['vif', vif],
['mac', mac]]
+ if self.be_mac:
+ val.append(['be_mac', self.get_be_mac()])
if self.bridge:
val.append(['bridge', self.bridge])
if self.script:
"""
return ':'.join(map(lambda x: "%02x" % x, self.mac))
+ def get_be_mac(self):
+ """Get the backend MAC address as a string.
+ """
+ return ':'.join(map(lambda x: "%02x" % x, self.be_mac))
+
def vifctl_params(self, vmname=None):
"""Get the parameters to pass to vifctl.
"""
msg = packMsg('netif_be_create_t',
{ 'domid' : self.controller.dom,
'netif_handle' : self.vif,
+ 'be_mac' : self.be_mac or [0, 0, 0, 0, 0, 0],
'mac' : self.mac })
self.getBackendInterface().writeRequest(msg, response=d)
return d
fn=append_value, default=[],
use="Add an IP address to the domain.")
-gopts.var('vif', val="mac=MAC,bridge=BRIDGE,script=SCRIPT,backend=DOM",
+gopts.var('vif', val="mac=MAC,be_mac=MAC,bridge=BRIDGE,script=SCRIPT,backend=DOM",
fn=append_value, default=[],
use="""Add a network interface with the given MAC address and bridge.
The vif is configured by calling the given configuration script.
If mac is not specified a random MAC address is used.
+ The MAC address of the backend interface can be selected with be_mac.
+ If not specified then the network backend chooses it's own MAC address.
If bridge is not specified the default bridge is used.
If script is not specified the default script is used.
If backend is not specified the default backend driver domain is used.
mac = d.get('mac')
if not mac:
mac = randomMAC()
+ be_mac = d.get('be_mac')
bridge = d.get('bridge')
script = d.get('script')
backend = d.get('backend')
ip = d.get('ip')
else:
mac = randomMAC()
+ be_mac = None
bridge = None
script = None
backend = None
ip = None
config_vif = ['vif']
config_vif.append(['mac', mac])
+ if be_mac:
+ config_vif.append(['be_mac', be_mac])
if bridge:
config_vif.append(['bridge', bridge])
if script:
(k, v) = b.strip().split('=', 1)
k = k.strip()
v = v.strip()
- if k not in ['mac', 'bridge', 'script', 'backend', 'ip']:
+ if k not in ['mac', 'be_mac', 'bridge', 'script', 'backend', 'ip']:
opts.err('Invalid vif specifier: ' + vif)
d[k] = v
vifs.append(d)
u32 netif_handle; /* 4: Domain-specific interface handle. */
u8 mac[6]; /* 8 */
u16 __pad1; /* 14 */
+ u8 be_mac[6]; /* 16 */
+ u16 __pad2; /* 22 */
/* OUT */
- u32 status; /* 16 */
-} PACKED netif_be_create_t; /* 20 bytes */
+ u32 status; /* 24 */
+} PACKED netif_be_create_t; /* 28 bytes */
/*
* CMSG_NETIF_BE_DESTROY: